iT邦幫忙

2022 iThome 鐵人賽

DAY 29
0

Autoencoder概念

在變數過多時,往往會使用許多不同的特徵選取的方法來選取重要的特徵,機器學習模型中常使用的變數挑選方法為正規化迴歸(Lasso, Ridge, Elastic net)。在深度學習中,可使用一個非監督式學習的類神經網路進行挑選,其結構可以用下面的圖來做範例,整個結構可分為Encoder、Bottleneck、Decoder。

https://ithelp.ithome.com.tw/upload/images/20221006/201512797YyD0Sve0D.png
圖片來源:連結

  1. Encoder:
    Encoder負責將原始資料(Input data)壓縮成低維的向量(Bottleneck),而壓縮後的向量(Bottleneck)則會被稱為特徵向量(latent vector/latent space),壓縮後的向量會減少資料的維度,因此在此Autoencoder擁有降維的作用。
    由於Encoder會由多層隱藏層(Hidden layer)組成,而Hidden layer中會使用activation function進行非線性轉換,因此所得到的特徵結合了多個不同的變數所帶有的資訊。
  2. Decoder:
    Decode負責將latent space還原成input data,盡可能將還原後的資料與原始資料相同。

如何衡量Autoencoder的表現?
-> 比較原始資料與還原後的資料之間的相似度,相似度越高,可判斷Autoencoder的表現較好,所選取的特徵向量較有代表性。

Autoencoder的種類

1.** Variational Autoencoder(VAE)**
https://ithelp.ithome.com.tw/upload/images/20221007/201512799rCM3CrG55.png
圖片來源:連結
為Autoencoder的進階版,其架構與Autoencoder相同,最大的差異在於Encoder所產生的結果。在Autoencoder將每筆資料視為獨立,因此Encoder產生的會是一個非連續的向量(One Hot Label),而VAE的Encoder所產生的則是連續數值,期望能夠利用VAE找到資料的分佈情形,因此輸出的則是平均數變異數。為了要考量encoder輸出包含變異數,因此則會在Loss function內加上限制。

  1. Sparse Autoencoder(SAE)
    https://ithelp.ithome.com.tw/upload/images/20221007/20151279R7yZEdS1Z6.png
    圖片來源:連結
    Sparse Autoencoder則是在Autoencoder的基礎上加上L1正規化,加上稀疏性的限制,在特徵稀疏的過程中,可以過濾掉無用的信息,使每個神經元可以用來辨識某些特定的特徵。

這裡目前列舉兩種,但Autoencoder有更多種類,如:Denoising AE, CNN/LSTM AutoEncoder等。

實作

詳細的autoencoder實作可參考:連結一, 連結二

讀取檔案(請參考上一篇)

由於本次實作不考量channel之間的關係,因此將每個channel所產生的時頻圖當作一個樣本,因此建立3維的矩陣儲存資料

### create 3D CNN
gesture = []
segment_store = []
segment_index =  [ i for i in range(0,11500,125)]
for segment in range(0,91):
    for channel in range(0,64):
        freq, times, spectrogram = signal.spectrogram(EMG_total.iloc[segment_index[segement]:segment_index[segement+1],channel], fs=25,nperseg=25)
        if channel == 0 and segment == 0:
            segment_store = spectrogram
        else:
            segment_store = np.dstack([segment_store,spectrogram])
        gesture.append(EMG_total.iloc[segment_index[segment],64])

data = segment_store  # dim = (13, 5, 5824)
gesture = np.array(gesture)  # dim = (5824,)
data = np.transpose(data, (2,0,1))  
data.shape # dim = (5824, 13, 5)

切分資料

autoencoder為非監督式學習方法,因此訓練時可選擇使用全部資料集或是部分資料集

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(data, gesture, test_size=0.2)  
x_train.shape  # dim = (4659, 13, 5)

autoencoder建立

encoder_input = keras.Input(shape=(13, 5, 1), name='img')
x = keras.layers.Flatten()(encoder_input)
encoder_output = keras.layers.Dense(32, activation="relu")(x)

encoder = keras.Model(encoder_input, encoder_output, name='encoder')

decoder_input = keras.layers.Dense(32, activation="relu")(encoder_output)
x = keras.layers.Dense(65, activation="relu")(decoder_input)
decoder_output = keras.layers.Reshape((13, 5, 1))(x)

opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)

autoencoder = keras.Model(encoder_input, decoder_output, name='autoencoder')
autoencoder.summary()
autoencoder.compile(optimizer='adam', loss='categorical_crossentropy')

https://ithelp.ithome.com.tw/upload/images/20221008/20151279JUTufisxY9.png

history = autoencoder.fit(
      x_train, x_train,
      epochs=100, 
      batch_size=250, validation_split=0.10)   

https://ithelp.ithome.com.tw/upload/images/20221008/20151279iwN6zehNTv.png

cluster

使用encoder所計算的feature當作資料的新的feature,利用K-Means進行分群

x_test_encoded = encoder.predict(x_test)

from sklearn import cluster
from sklearn import metrics
# KMeans 演算法
pred_kmean = cluster.KMeans(n_clusters = 4,algorithm="elkan")
pred_kmean.fit_predict(x_test_encoded)
pred_labels = pred_kmean.labels_
print(metrics.classification_report(pred_labels, y_test))

https://ithelp.ithome.com.tw/upload/images/20221008/20151279sxi3qywp4t.png

本次實作僅提供概念上的實作,根據分群結果,其實結果並不理想。可能的原因在於不同channel的數值差異較大,因此需將這個部分納入考量,或是可使用更加複雜的autoencoder結構來改善。


上一篇
[Day 28] 3D CNN
下一篇
[Day 30] 比賽尾聲
系列文
人類行為數據分析- 以R和Python進行實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言